/**
 * This file is part of aion-emu <aion-emu.com>.
 *
 *  aion-emu is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  aion-emu is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with aion-emu.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aionemu.gameserver.network.aion.serverpackets;

import com.aionemu.gameserver.configs.main.CustomConfig;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.gameobjects.player.PlayerCommonData;
import com.aionemu.gameserver.model.gameobjects.stats.PlayerGameStats;
import com.aionemu.gameserver.model.gameobjects.stats.PlayerLifeStats;
import com.aionemu.gameserver.model.gameobjects.stats.Stat;
import com.aionemu.gameserver.model.gameobjects.stats.StatEnum;
import com.aionemu.gameserver.network.aion.AbstractAionServerPacket;
import com.aionemu.gameserver.network.aion.GameClient;
import com.aionemu.gameserver.utils.gametime.GameTimeManager;

/**
 * In this packet Server is sending User Info?
 * 
 * @author Lyahim, -Nemesiss-
 * @author Lyahim, Luno
 */
public class SM_STATS_INFO extends AbstractAionServerPacket<GameClient>
{
	/**
	 * Player that stats info will be send
	 */
	private final Player			player;
	private final PlayerGameStats	pgs;
	private final PlayerLifeStats	pls;
	private final PlayerCommonData	pcd;

	/**
	 * Constructs new <tt>SM_UI</tt> packet
	 * 
	 * @param player
	 */
	public SM_STATS_INFO(Player player)
	{
		this.player = player;
		this.pcd = player.getObjectTemplate();
		this.pgs = player.getGameStats();
		this.pls = player.getLifeStats();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void writeImpl(GameClient client)
	{
		writeD(player.getObjectId());
		writeD(GameTimeManager.getGameTime().getTime()); // Minutes since 1/1/00 00:00:00

		Stat power = pgs.getPower();
		writeH(power.getCurrentInt());// [current power]
		Stat health = pgs.getHealth();
		writeH(health.getCurrentInt());// [current health]
		Stat accuracy = pgs.getAccuracy();
		writeH(accuracy.getCurrentInt());// [current accuracy]
		Stat agility = pgs.getAgility();
		writeH(agility.getCurrentInt());// [current agility]
		Stat knowledge = pgs.getKnowledge();
		writeH(knowledge.getCurrentInt());// [current knowledge]
		Stat will = pgs.getWill();
		writeH(will.getCurrentInt());// [current will]

		writeH(pgs.getStat(StatEnum.WATER_RESISTANCE, 0).getCurrentInt());// [current water]
		writeH(pgs.getStat(StatEnum.WIND_RESISTANCE, 0).getCurrentInt());// [current wind]
		writeH(pgs.getStat(StatEnum.EARTH_RESISTANCE, 0).getCurrentInt());// [current earth]
		writeH(pgs.getStat(StatEnum.FIRE_RESISTANCE, 0).getCurrentInt());// [current fire]
		writeH(pgs.getStat(StatEnum.LIGHT_RESISTANCE, 0).getCurrentInt());
		writeH(pgs.getStat(StatEnum.DARK_RESISTANCE, 0).getCurrentInt());

		writeH(player.getLevel());// [level]

		// something like very dynamic
		writeH(0); // [unk]
		writeH(0);// [unk]
		writeH(0);// [unk]

		writeQ(pcd.getExpNeed());// [xp till next lv]
		writeQ(pcd.getExpRecoverable()); // [recoverable exp]
		writeQ(pcd.getExpShown()); // [current xp]

		writeD(0); // [unk]
		Stat maxHp = pgs.getMaxHP();
		writeD(maxHp.getCurrentInt()); // [max hp]
		writeD(pls.getCurrentHp());// [current hp]

		Stat maxMp = pgs.getMaxMP();
		writeD(maxMp.getCurrentInt());// [max mana]
		writeD(pls.getCurrentMp());// [current mana]

		writeH(pgs.getStat(StatEnum.MAXDP, 4000).getCurrentInt());// [max dp]
		writeH(pcd.getDp());// [current dp]

		Stat flyTime = pgs.getStat(StatEnum.FLY_TIME, CustomConfig.BASE_FLYTIME);
		writeD(flyTime.getCurrentInt());// [max fly time]

		writeD(pls.getCurrentFp());// [current fly time]

		writeC(player.getFlyState());// [fly state]
		writeC(0);// [unk]

		Stat mainHandPower = pgs.getMainHandPAttack();
		writeH(mainHandPower.getCurrentInt()); // [current main hand attack]
		Stat offHandPower = pgs.getOffHandPAttack();
		writeH(offHandPower.getCurrentInt()); // [off hand attack]
		Stat pDef = pgs.getPDef();
		writeH(pDef.getCurrentInt());// [current pdef]
		Stat mainHandMagic = pgs.getMainHandMAttack();
		writeH(mainHandMagic.getCurrentInt());// [current magic attack ?]
		Stat mResist = pgs.getMagicalResist();
		writeH(mResist.getCurrentInt()); // [current mres]

		Stat attackRange = pgs.getAttackRange();
		writeF(attackRange.getCurrent() / 1000f);// attack range
		Stat attackSpeed = pgs.getAttackSpeed();
		writeH(attackSpeed.getCurrentInt());// attack speed
		Stat evasion = pgs.getEvasion();
		writeH(evasion.getCurrentInt());// [current evasion]
		Stat parry = pgs.getParry();
		writeH(parry.getCurrentInt());// [current parry]
		Stat block = pgs.getBlock();
		writeH(block.getCurrentInt());// [current block]
		Stat mainPCrit = pgs.getMainHandPCritical();
		writeH(mainPCrit.getCurrentInt());// [current main hand crit rate]
		Stat offPCrit = pgs.getOffHandPCritical();
		writeH(offPCrit.getCurrentInt());// [current off hand crit rate]
		Stat mainPAccuracy = pgs.getMainHandPAccuracy();
		writeH(mainPAccuracy.getCurrentInt());// [current main_hand_accuracy]
		Stat offPAccuracy = pgs.getOffHandPAccuracy();
		writeH(offPAccuracy.getCurrentInt());// [current off_hand_accuracy]
		writeH(100);// [unk]
		Stat mAccuracy = pgs.getMagicalAccuracy();
		writeH(mAccuracy.getCurrentInt());// [current magic accuracy]
		Stat critSpell = pgs.getMagicalCritical();
		writeH(critSpell.getCurrentInt()); // [current concentration]
		writeH(200); // [old current magic boost location]
		writeF(pgs.getStat(StatEnum.BOOST_CASTING_TIME, 1000).getCurrent()/1000f);// [unk] 1.9 version
		writeH(40);// [unk] 1.9 version
		Stat magicBoost = pgs.getMagicalBoost();
		writeH(magicBoost.getCurrentInt()); // [current magic boost] 1.9 version
		writeH(pgs.getStat(StatEnum.BOOST_HEAL, 0).getCurrentInt()); // [current boost_heal]
		writeH(pgs.getStat(StatEnum.CRITICAL_RESIST, 0).getCurrentInt());
		writeH(pgs.getStat(StatEnum.MAGICAL_CRITICAL_RESIST, 0).getCurrentInt());
		writeH(pgs.getStat(StatEnum.PHYSICAL_CRITICAL_DAMAGE_REDUCE, 0).getCurrentInt());
		writeH(pgs.getStat(StatEnum.MAGICAL_CRITICAL_DAMAGE_REDUCE, 0).getCurrentInt());
		writeH(20511);// [unk] 1.9 version

		writeD((27 + (player.getObjectTemplate().getCubeSize() * 9)));// [unk]

		writeD(player.getInventory().size());// [unk]
		writeD(0);// [unk]
		writeD(0);// [unk]
		writeD(pcd.getPlayerClass().getClassId());// [Player Class id]

		writeQ(0);// [unk] 1.9 version
		writeQ(0);// Current energy of repose 1.9
		writeQ(251141);// Max energy of repose 1.9
		writeQ(0);// [unk] 1.9 version

		//writeQ(buf, 4020244);// [current energy of repose]
		//writeQ(buf, 4720968);// [max energy of repose]

		writeH(power.getBaseInt());// [base power]
		writeH(health.getBaseInt());// [base health]

		writeH(accuracy.getBaseInt());// [base accuracy]
		writeH(agility.getBaseInt());// [base agility]

		writeH(knowledge.getBaseInt());// [base knowledge]
		writeH(will.getBaseInt());// [base will]

		writeH(0);// [base water res]
		writeH(0);// [base water res]

		writeH(0);// [base earth resist]
		writeH(0);// [base water res]

		writeD(0);// [unk]

		writeD(maxHp.getBaseInt());// [base hp]

		writeD(maxMp.getBaseInt());// [base mana]

		writeD(4000);// [base dp]
		writeD(flyTime.getBaseInt());// [fly time]

		writeH(mainHandPower.getBaseInt());// [base main hand attack]
		writeH(offHandPower.getBaseInt());// [base off hand attack]
		writeH(mainHandMagic.getBaseInt()); // [base magic attack ?] 
		
		writeH(pDef.getBaseInt()); // [base pdef]

		writeH(mResist.getBaseInt()); // [base magic res]

		writeH(0); // [unk]

		writeF(attackRange.getBaseInt() / 1000f);// [current attack range]

		writeH(evasion.getBaseInt()); // [base evasion]

		writeH(parry.getBaseInt()); // [base parry]

		writeH(block.getBaseInt()); // [base block]

		writeH(mainPCrit.getBaseInt()); // [base main hand crit rate]
		writeH(offPCrit.getBaseInt()); // [base off hand crit rate]
		writeH(critSpell.getBaseInt()); // [base or current MAGICAL crit rate] VERSION 1.9 
		writeH(0);
		
		writeH(mainPAccuracy.getBaseInt()); // [base main hand accuracy]
		writeH(offPAccuracy.getBaseInt()); // [base off hand accuracy]

		writeH(1);
		writeH(mAccuracy.getBaseInt());// [base magic accuracy]

		writeH(0); // [unk] VERSION 1.9 
		
		writeH(magicBoost.getBaseInt());// [base magic boost]
		writeH(0); // [unk]
		writeH(0); // [unk] 
		writeH(0); // [unk]
		writeH(0); // [unk] 
		writeH(0); // [unk]
	}
}
